import re

from django_redis import get_redis_connection
from rest_framework import serializers

from users.models import User


class CreateRoleSerializer(serializers.ModelSerializer):
    role_choices = (
        (2, "普通管理员"),
        (3, "客服"),

    )
    GENDER_CHOICES = (
        (1, '男'),
        (2, '女'),
    )
    username = serializers.CharField(required=True, label="用户名")
    password = serializers.CharField(required=True, write_only=True, label="用户密码")
    password2 = serializers.CharField(required=True, write_only=True, label="确认密码")
    gender = serializers.ChoiceField(choices=GENDER_CHOICES, label="性别")
    realname = serializers.CharField(max_length=32, label="真实姓名")
    role = serializers.ChoiceField(choices=role_choices, label="用户角色", write_only=True, default=2)

    class Meta:
        model = User
        fields = ('username', 'password', 'password2', 'gender', 'role', 'realname')

    def validate(self, attrs):
        """
        验证用户名
        """
        # 一个用户名只能注册一次
        count = User.objects.filter(username=attrs['username']).count()
        if count > 0:
            raise serializers.ValidationError('该账号已被注册，请重新选择')
        # 校验俩个密码是否一致
        if attrs['password'] != attrs['password2']:
            raise serializers.ValidationError('俩次输入的密码不一致，请重新输入')
        return attrs

    def create(self, validated_data):
        """
        保存
        """
        # 保存用户密码
        del validated_data['password2']
        user = super().create(validated_data)
        user.set_password(validated_data['password'])
        user.save()
        return user


class AdminChangeMobileSerializer(serializers.ModelSerializer):
    """
    管理员添加/修改手机号码
    """
    sms_code = serializers.CharField(min_length=6, max_length=6, write_only=True, label="短信验证码")

    class Meta:
        model = User
        fields = ('mobile', 'sms_code')
        extra_kwargs = {
            'mobile': {
                'required': True,
                'write_only': True,
            },
        }

    def validate(self, attrs):
        # 校验用户是否存在
        username = self.context['view'].kwargs['username']
        try:
            username = User.objects.get(username=username, is_deleted=False)
        except User.DoesNotExist:
            raise serializers.ValidationError("用户不存在")

        # 校验短信验证码
        redis_conn = get_redis_connection('verify_codes')
        mobile = attrs['mobile']
        real_sms_code = redis_conn.get('sms_%s' % mobile)
        if real_sms_code is None:
            raise serializers.ValidationError('无效的短信验证码')
        if attrs['sms_code'] != real_sms_code.decode():
            raise serializers.ValidationError('短信验证码错误')

        return attrs

    def update(self, instance, validate_data):
        del validate_data['sms_code']
        instance.mobile = validate_data['mobile']
        instance.save()
        return instance


# class AdminDetailSerializer(serializers.ModelSerializer):
#     """
#     展示管理员个人信息
#     """
#     class Meta:
#         model = User
#         fields = ('realname','mobile','gender','role',)


class ForgetAdminPasswordSerializer(serializers.ModelSerializer):
    """
    忘记密码
    """
    mobile = serializers.CharField(min_length=11, max_length=11, write_only=True, required=True)
    sms_code = serializers.CharField(min_length=6, max_length=6, write_only=True, required=True)
    password2 = serializers.CharField(label="确认密码", write_only=True, required=True)

    class Meta:
        model = User
        fields = ('password', 'password2', 'sms_code', 'mobile')
        extra_kwargs = {
            'password': {
                'write_only': True
            }
        }

    def validate(self, attrs):
        # 校验用户名
        username = self.context['view'].kwargs['username']
        try:
            check_user = User.objects.get(username=username, is_deleted=False)
        except User.DoesNotExist:
            raise serializers.ValidationError('用户不存在')

        # 校验用户名跟手机号码是否绑定
        try:
            check_user_mobile = User.objects.get(username=username, mobile=attrs['mobile'])
        except User.DoesNotExist:
            raise serializers.ValidationError('手机号绑定错误')

        # 校验俩次输入密码是否一致
        if attrs['password'] != attrs['password2']:
            raise serializers.ValidationError('俩次密码输入不一致')

        # 校验手机号码
        if not re.match(r'^1[3-9]\d{9}$', attrs['mobile']):
            raise serializers.ValidationError('手机号格式错误')

        # 校验短信验证码
        redis_conn = get_redis_connection('verify_codes')
        mobile = attrs['mobile']
        real_sms_code = redis_conn.get('sms_%s' % mobile)
        if real_sms_code is None:
            raise serializers.ValidationError('无效的短信验证码')
        if attrs['sms_code'] != real_sms_code.decode():
            raise serializers.ValidationError('短信验证码错误')

        return attrs

    def update(self, instance, validated_data):
        del validated_data['password2']
        del validated_data['sms_code']
        del validated_data['mobile']
        instance.set_password(validated_data['password'])
        instance.save()
        return instance


class ChangeAdminPasswordSerializer(serializers.ModelSerializer):
    current_password = serializers.CharField(write_only=True, required=True, label="当前密码")
    password1 = serializers.CharField(label="新密码", write_only=True, required=True)
    password2 = serializers.CharField(label="确认密码", write_only=True, required=True, )

    class Meta:
        model = User
        fields = ('current_password', 'password1', 'password2',)

    def validate(self, attrs):
        id = self.context['view'].kwargs['pk']
        try:
            user = User.objects.get(id=id)
        except User.DoesNotExist:
            raise ValueError("用户不存在!")
        if user.check_password(attrs['current_password']):
            if attrs['current_password'] == attrs['password1']:
                raise ValueError("旧密码与新密码一致，请重新修改")
            if attrs['password1'] != attrs['password2']:
                raise ValueError("俩次输入的密码不一致")
            return attrs
        else:
            raise ValueError("用户密码错误")

    def update(self, instance, validated_data):
        instance.set_password(validated_data['password1'])
        instance.save()
        return instance


class DeleteAdminSerializer(serializers.ModelSerializer):
    """
    删除管理员
    """

    class Meta:
        model = User
        fields = ('is_deleted',)

    def validate(self, attrs):
        username = self.context['view'].kwargs['username']
        try:
            user = User.objects.get(username=username, is_deleted=False)
        except User.DoesNotExist:
            raise serializers.ValidationError("用户不存在")
        return attrs

    def update(self, instance, validated_data):
        instance.is_deleted = True
        instance.save()
        return instance


class ChangeAdminStatusSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ('active_status',)

    def update(self, instance, validated_data):
        instance.active_status = validated_data['active_status']
        instance.save()
        return instance


class UserMobileSendSMSCodeSerializer(serializers.Serializer):
    """
    检测是否多次发送短信验证码
    """

    def validate(self, attrs):
        # redis中发送短信验证码的标志 send_flag_<mobile> : 1  由redis维护60s的有效期
        redis_conn = get_redis_connection('verify_codes')
        mobile = self.context['view'].kwargs.get('mobile')
        if mobile:
            send_flag = redis_conn.get('send_flag_%s' % mobile)
            if send_flag:
                raise serializers.ValidationError('发送短信次数过于频繁')
        return attrs


class DisplayAllAdminSerializer(serializers.ModelSerializer):
    username = serializers.CharField(read_only=True, label="用户名")
    mobile = serializers.CharField(min_length=11, max_length=11, read_only=True, label="手机号码")
    date_joined = serializers.DateTimeField(read_only=True, label="加入时间")
    role = serializers.IntegerField(read_only=True, label="角色")
    active_status = serializers.IntegerField(read_only=True, label="启用状态")
    realname = serializers.CharField(read_only=True, label="真实姓名")
    gender = serializers.IntegerField(read_only=True, label="性别")

    class Meta:
        model = User
        fields = ('username', 'mobile', 'date_joined', 'role', 'active_status', 'realname', 'gender')
        filter_fields = ('role',)


class SuperUserChangeAdminSerializer(serializers.ModelSerializer):
    password2 = serializers.CharField(required=True, write_only=True, label="确认密码")

    class Meta:
        model = User
        fields = ('password', 'password2')
        extra_kwargs = {
            'password': {
                'required': True,
                'write_only': True
            }
        }

    def validate(self, attrs):
        username = self.context['view'].kwargs['username']
        try:
            user = User.objects.get(username=username)
        except User.DoesNotExist:
            raise serializers.ValidationError("用户不存在!")
        if attrs['password'] != attrs['password2']:
            raise serializers.ValidationError("俩次输入的密码不一致")
        return attrs

    def update(self, instance, validated_data):
        del validated_data['password2']
        instance.set_password(validated_data['password'])
        instance.save()
        return instance
